{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "sss = '{\"fes\":{\"number\":4,\"values\":[{\"id\":\"101\",\"work\":false,\"error\":false},{\"id\":\"102\",\"work\":false,\"error\":false},{\"id\":\"103\",\"work\":false,\"error\":false},{\"id\":\"104\",\"work\":false,\"error\":false}]},\"fs\":{\"numJB\":\"0\",\"oc\":{\"value\":\"25\",\"error\":false},\"co\":{\"value\":\"0.1\",\"error\":false},\"voc\":{\"value\":\"20\",\"error\":false},\"fog\":{\"value\":\"0.01\",\"error\":false}},\"fq\":{\"area\":\"1\",\"JBlevel\":\"0\",\"auto\":true,\"start\":false,\"shutdown\":false,\"rain\":false}}'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import json"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "dict"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(json.loads(sss))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 251,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'fes': {'number': 4,\n",
       "  'values': [{'id': '101', 'work': False, 'error': True},\n",
       "   {'id': '102', 'work': False, 'error': True},\n",
       "   {'id': '103', 'work': False, 'error': True},\n",
       "   {'id': '104', 'work': False, 'error': False}]},\n",
       " 'fs': {'numJB': '0',\n",
       "  'FeelerNumber': '4',\n",
       "  'oc': {'id': '201', 'value': '25', 'error': True},\n",
       "  'co': {'id': '202', 'value': '0.1', 'error': False},\n",
       "  'voc': {'id': '203', 'value': '20', 'error': False},\n",
       "  'fog': {'id': '204', 'value': '0.01', 'error': True}},\n",
       " 'fq': {'area': '1',\n",
       "  'JBlevel': '0',\n",
       "  'Mid': '1',\n",
       "  'Mtype': 'Light',\n",
       "  'auto': True,\n",
       "  'start': False,\n",
       "  'shutdown': False,\n",
       "  'rain': False,\n",
       "  'startRain': False}}"
      ]
     },
     "execution_count": 251,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "json.loads('{\"fes\":{\"number\":4,\"values\":[{\"id\":\"101\",\"work\":false,\"error\":true},{\"id\":\"102\",\"work\":false,\"error\":true},{\"id\":\"103\",\"work\":false,\"error\":true},{\"id\":\"104\",\"work\":false,\"error\":false}]},\"fs\":{\"numJB\":\"0\",\"FeelerNumber\":\"4\",\"oc\":{\"id\":\"201\",\"value\":\"25\",\"error\":true},\"co\":{\"id\":\"202\",\"value\":\"0.1\",\"error\":false},\"voc\":{\"id\":\"203\",\"value\":\"20\",\"error\":false},\"fog\":{\"id\":\"204\",\"value\":\"0.01\",\"error\":true}},\"fq\":{\"area\":\"1\",\"JBlevel\":\"0\",\"Mid\":\"1\",\"Mtype\":\"Light\",\"auto\":true,\"start\":false,\"shutdown\":false,\"rain\":false,\"startRain\":false}}')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "9.45"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "float('9.45')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 378,
   "metadata": {},
   "outputs": [],
   "source": [
    "import json\n",
    "\n",
    "class DataFormer:\n",
    "    _ReportError_read = '__DataFormer_report_read_error___@_'\n",
    "    _ReportError_func = '__DataFormer_report_func_error___@_'\n",
    "    _ReportError_unkn = '__DataFormer_report_unkn_error___@_'\n",
    "    _ReportError_crce = '__DataFormer_report_crce_error___@_'\n",
    "    _dicMch2Num = {'oc' : 1, 'co' : 2, 'voc' : 3, 'fog' : 4, 'fireEnder' : 5}\n",
    "    _dicNum2Mch = {1 : 'oc', 2 : 'co', 3 : 'voc', 4 : 'fog', 5 : 'fireEnder'}\n",
    "    _dicMtype2Chr = {'Light' : chr(0x00) + chr(0x00), 'Normal' : chr(0x00) + chr(0x01)}\n",
    "    _dicChr2Mtype = {chr(0x00) + chr(0x00) : 'Light', chr(0x00) + chr(0x01) : 'Normal'}\n",
    "    _testdata = json.loads('{\"fes\":{\"number\":4,\"values\":[{\"id\":\"101\",\"work\":false,\"error\":true},{\"id\":\"102\",\"work\":false,\"error\":true},{\"id\":\"103\",\"work\":false,\"error\":true},{\"id\":\"104\",\"work\":false,\"error\":false}]},\"fs\":{\"numJB\":\"0\",\"FeelerNumber\":\"4\",\"oc\":{\"id\":\"201\",\"value\":\"25\",\"error\":true},\"co\":{\"id\":\"202\",\"value\":\"0.1\",\"error\":false},\"voc\":{\"id\":\"203\",\"value\":\"20\",\"error\":false},\"fog\":{\"id\":\"204\",\"value\":\"0.01\",\"error\":true}},\"fq\":{\"area\":\"1\",\"JBlevel\":\"0\",\"Mid\":\"1\",\"Mtype\":\"Light\",\"auto\":true,\"start\":false,\"shutdown\":false,\"rain\":false,\"startRain\":false}}')\n",
    "    _report05fail = chr(0xa0) + chr(0x01) + chr(0x01) + chr(0x00)\n",
    "    _report04fail = chr(0x90) + chr(0x01) + chr(0x01) + chr(0x00)\n",
    "    _report03fail = chr(0x80) + chr(0x01) + chr(0x01) + chr(0x00)\n",
    "    _report02fail = chr(0x70) + chr(0x01) + chr(0x01) + chr(0x00) \n",
    "    _report01fail = chr(0x60) + chr(0x01) + chr(0x01) + chr(0x00) \n",
    "    _Fcodes = (0x60, 0x70, 0x80, 0x90, 0xa0)\n",
    "    def __init__(self):\n",
    "        self.dic = {}\n",
    "\n",
    "    def Snum2ChrBit16(self, num):\n",
    "        num = int(num)\n",
    "        return chr((num >> 8) & 0xff) + chr(num & 0xff)\n",
    "\n",
    "    #精度保留三位小数\n",
    "    def Sfloat2ChrBit16(self, num):\n",
    "        return self.Snum2ChrBit16(float(num) * 1000)\n",
    "\n",
    "    def SBit16toNum(self, data):\n",
    "        return (ord(data[0]) << 8) + ord(data[1])\n",
    "    \n",
    "    def SBit16toFloat(self, data):\n",
    "        return self.SBit16toNum(data) / 1000\n",
    "\n",
    "    def Snum2ChrBit8(self, num):\n",
    "        return chr(int(num))\n",
    "    \n",
    "    def SBit8toNum(self, data):\n",
    "        return ord(data)\n",
    "\n",
    "    def setDic(self, dic):\n",
    "        self.dic = dic\n",
    "\n",
    "    def parseReplay(self):\n",
    "        pass\n",
    "\n",
    "    def parseReport(self, data):\n",
    "        ret = DataFormer._ReportError_unkn\n",
    "        crc = ord(data[-2])\n",
    "        crc_now = self.crc8(data[ : -2] + data[-1])\n",
    "        Fcode = ord(data[5])\n",
    "        if crc_now != crc:\n",
    "            return DataFormer._ReportError_crce\n",
    "        elif Fcode not in DataFormer._Fcodes:\n",
    "            return DataFormer._ReportError_func\n",
    "        else:\n",
    "            info = data[8 : -2]\n",
    "            if Fcode == 0x60:\n",
    "                ret = self.parseReport01(info)\n",
    "            elif Fcode == 0x70:\n",
    "                ret = self.parseReport02(info)\n",
    "            elif Fcode == 0x80:\n",
    "                ret = self.parseReport03(info)\n",
    "            elif Fcode == 0x90:\n",
    "                ret = self.parseReport04(info)\n",
    "            elif Fcode == 0xa0:\n",
    "                ret = self.parseReport05(info)\n",
    "        return ret\n",
    "    def formReplay(self):\n",
    "        pass\n",
    "\n",
    "    def formReport(self):\n",
    "        lst = [\n",
    "            self.wapperOfFormReport(0x60, self.formReport01()), \n",
    "            self.wapperOfFormReport(0x70, self.formReport02()), \n",
    "            self.wapperOfFormReport(0x80, self.formReport03()), \n",
    "            self.wapperOfFormReport(0x90, self.formReport04()), \n",
    "            self.wapperOfFormReport(0xa0, self.formReport05()), \n",
    "        ]\n",
    "        return lst\n",
    "\n",
    "    def crc8(self, data):\n",
    "        N = 8\n",
    "        loc = [8, 2, 1, 0]\n",
    "        p = [0 for i in range(N + 1)]\n",
    "        for i in loc: p[i] = 1\n",
    "\n",
    "        info = []\n",
    "        for ch in data:\n",
    "            tmp = []\n",
    "            ch = ord(ch)\n",
    "            for i in range(8):\n",
    "                tmp.append(ch & 1)\n",
    "                ch >>= 1\n",
    "            info.extend(tmp[ : : -1])\n",
    "\n",
    "        leng = len(info)\n",
    "        n = N + 1\n",
    "        for i in range(N):\n",
    "            info.append(0)\n",
    "        \n",
    "        for i in range(leng):\n",
    "            if info[i] == 1:\n",
    "                for j in range(n):\n",
    "                    info[j + i] = info[j + i] ^ p[j]\n",
    "\n",
    "        yu = info[-N::]\n",
    "\n",
    "        ret = 0\n",
    "        for each in yu:\n",
    "            ret <<= 1\n",
    "            ret |= each\n",
    "\n",
    "        return ret\n",
    "\n",
    "    def wapperOfFormReport(self, Funcode, txt):\n",
    "        fq = self.dic['fq']\n",
    "        assert 'Mid' in fq\n",
    "        success = True if ord(txt[1]) == 0x00 else False\n",
    "        length = 10 + len(txt)\n",
    "        Mid = fq['Mid']\n",
    "        ret = 'QN' # 同步字符 2\n",
    "        ret += self.Snum2ChrBit16(length) # 长度 2\n",
    "        ret += self.Snum2ChrBit8(Mid) # ID 1\n",
    "        ret += self.Snum2ChrBit8(Funcode) # 功能码 1\n",
    "        ret += self.Snum2ChrBit8(success) # 读取成功失败情况 1\n",
    "        ret += txt # 报文 N\n",
    "        ret += 'E' # 结束符  1\n",
    "        crc = self.crc8(ret)\n",
    "        ret = ret[ : -1] + chr(crc) + ret[-1] # CRC 1\n",
    "        return ret\n",
    "\n",
    "\n",
    "    def formReport05(self):\n",
    "        ret = ''\n",
    "        try:\n",
    "            ret += chr(0xa0) + chr(0x00) + chr(0x01)\n",
    "            fes = self.dic['fes']\n",
    "            fq = self.dic['fq']\n",
    "            assert len(fes['values']) > 0\n",
    "            assert fes['number'] == len(fes['values'])\n",
    "            assert 'area' in fq\n",
    "            ret += chr(len(fes['values'])) #长度 1\n",
    "            for each in fes['values']:\n",
    "                ret += self.Snum2ChrBit16(fq['area']) # 防护区 2\n",
    "                ret += self.Snum2ChrBit16(each['id']) #each id 2\n",
    "                ret += self.Snum2ChrBit16(each['work']) #each 状态 2\n",
    "        except Exception:\n",
    "            ret = DataFormer._report05fail\n",
    "        return ret\n",
    "\n",
    "    def parseReport05(self, data):\n",
    "        ret = []\n",
    "        try:\n",
    "            if data[0] != chr(0xa0): return self._ReportError_func\n",
    "            if data[1] != chr(0x00): return self._ReportError_read\n",
    "            now = 4\n",
    "            for i in range(ord(data[3])):\n",
    "                tmp, dic = data[now : now + 6], {}\n",
    "                dic['area'] = self.SBit16toNum(tmp[0 : 2])\n",
    "                dic['id'] = self.SBit16toNum(tmp[2 : 4])\n",
    "                dic['work'] = self.SBit16toNum(tmp[4 : 6])\n",
    "                ret.append(dic)\n",
    "                now += 6\n",
    "        except Exception:\n",
    "            ret = DataFormer._ReportError_unkn\n",
    "        return ret\n",
    "\n",
    "    def formReport04(self):\n",
    "        ret = ''\n",
    "        try:\n",
    "            ret += chr(0x90) + chr(0x00) + chr(0x01)\n",
    "            fs = self.dic['fs']\n",
    "            fq = self.dic['fq']\n",
    "            assert 'numJB' in fs\n",
    "            assert 'oc' in fs\n",
    "            assert 'co' in fs\n",
    "            assert 'fog' in fs\n",
    "            assert 'voc' in fs\n",
    "            assert 'area' in fq\n",
    "            assert 'Mtype' in fq\n",
    "            assert 'Mid' in fq\n",
    "            assert 'JBlevel' in fq\n",
    "            ret += chr(4 + len(fs) - 1 + 3) # 长度 1\n",
    "            ret += chr(0xff) + chr(0xff) # 预留 2\n",
    "            ret += self.Snum2ChrBit16(fq['area']) #防护区 2\n",
    "            ret += DataFormer._dicMtype2Chr[fq['Mtype']] # 设备类型 2\n",
    "            ret += self.Snum2ChrBit16(fq['Mid']) # 设备ID 2\n",
    "            ret += self.Snum2ChrBit16(fq['JBlevel']) # 警报等级 2\n",
    "            ret += self.Sfloat2ChrBit16(fs['oc']['value']) # 温度 2 float精度三位小数\n",
    "            ret += self.Sfloat2ChrBit16(fs['co']['value']) # CO 2 float精度三位小数\n",
    "            ret += self.Sfloat2ChrBit16(fs['voc']['value']) # VOC 2 float精度三位小数\n",
    "            ret += self.Sfloat2ChrBit16(fs['fog']['value']) # FOG 2 float精度三位小数\n",
    "            ret += chr(0xff) + chr(0xff) # 预留 2\n",
    "            ret += chr(0xff) + chr(0xff) # 预留 2\n",
    "            ret += chr(0xff) + chr(0xff) # 预留 2\n",
    "        except Exception as e:\n",
    "            #print(e)\n",
    "            ret = DataFormer._report04fail\n",
    "        return ret\n",
    "\n",
    "    def parseReport04(self, data):\n",
    "        ret = {}\n",
    "        try:\n",
    "            if data[0] != chr(0x90): return self._ReportError_func\n",
    "            if data[1] != chr(0x00): return self._ReportError_read\n",
    "            now = 3\n",
    "            ret['length'] = ord(data[now])\n",
    "            now += 1\n",
    "            #预留\n",
    "            now += 2\n",
    "            ret['area'] = self.SBit16toNum(data[now : now + 2]) # 防护区 2\n",
    "            now += 2\n",
    "            ret['Mtype'] = DataFormer._dicChr2Mtype[data[now : now + 2]] # 设备类型\n",
    "            now += 2\n",
    "            ret['Mid'] = self.SBit16toNum(data[now : now + 2]) # 设备ID\n",
    "            now += 2\n",
    "            ret['JBlevel'] = self.SBit16toNum(data[now : now + 2]) # 警报等级\n",
    "            now += 2\n",
    "            ret['oc'] = self.SBit16toFloat((data[now : now + 2])) # oc\n",
    "            now += 2\n",
    "            ret['co'] = self.SBit16toFloat((data[now : now + 2])) # co\n",
    "            now += 2\n",
    "            ret['voc'] = self.SBit16toFloat((data[now : now + 2])) # voc\n",
    "            now += 2\n",
    "            ret['fog'] = self.SBit16toFloat((data[now : now + 2])) # fog\n",
    "            # 预留\n",
    "        except Exception as e:\n",
    "            #print(e)\n",
    "            ret = self._ReportError_unkn\n",
    "        return ret\n",
    "\n",
    "    def formReport03(self):\n",
    "        ret = ''\n",
    "        try:\n",
    "            ret += chr(0x80) + chr(0x00) + chr(0x01)\n",
    "            fq = self.dic['fq']\n",
    "            fes = self.dic['fes']\n",
    "            fs = self.dic['fs']\n",
    "            assert len(fes['values']) > 0\n",
    "            assert fes['number'] == len(fes['values'])\n",
    "            assert 'JBlevel' in fq\n",
    "            assert 'numJB' in fs\n",
    "            assert 'oc' in fs\n",
    "            assert 'co' in fs\n",
    "            assert 'fog' in fs\n",
    "            assert 'voc' in fs\n",
    "            assert 'auto' in fq\n",
    "            assert 'shutdown' in fq\n",
    "            assert 'start' in fq\n",
    "            assert 'rain' in fq\n",
    "            assert 'startRain' in fq\n",
    "            ret += chr(11 + 1) # 信息个数 1\n",
    "            ret += chr(0xff) + chr(0xff) #预留 2\n",
    "            ret += self.Snum2ChrBit16(fq['area']) #防护区 2\n",
    "            ret += self.Snum2ChrBit16(fq['JBlevel']) #警报等级 2\n",
    "            GZcnt = 0\n",
    "            for each in fes['values']:\n",
    "                if each['error'] == True:\n",
    "                    GZcnt += 1\n",
    "            for each in fs.values():\n",
    "                if type(each) == dict:\n",
    "                    if each['error'] == True:\n",
    "                        GZcnt += 1\n",
    "            ret += self.Snum2ChrBit16(GZcnt) #故障 2\n",
    "            ret += self.Snum2ChrBit16(1 if fq['auto'] == False else 0) # 手动模式 2\n",
    "            ret += self.Snum2ChrBit16(1 if fq['auto'] == True else 0) # 自动模式 2\n",
    "            ret += self.Snum2ChrBit16(fq['start']) # 手动启动  2\n",
    "            ret += self.Snum2ChrBit16(fq['shutdown']) # 手动急停 2\n",
    "            ret += chr(0xff) + chr(0xff) # 启动控制\n",
    "            ret += chr(0xff) + chr(0xff) # 延时\n",
    "            ret += self.Snum2ChrBit16(fq['startRain']) # 启动喷洒\n",
    "            ret += self.Snum2ChrBit16(fq['rain']) # 喷洒\n",
    "            ret += chr(0xff) + chr(0xff) # 预留\n",
    "        except Exception as e:\n",
    "            print(e)\n",
    "            ret = DataFormer._report03fail\n",
    "        return ret\n",
    "\n",
    "    def parseReport03(self, data):\n",
    "        ret = {}\n",
    "        try:\n",
    "            if data[0] != chr(0x80): return self._ReportError_func\n",
    "            if data[1] != chr(0x00): return self._ReportError_read\n",
    "            now = 3\n",
    "            ret['length'] = ord(data[now])\n",
    "            now += 1\n",
    "            # 预留\n",
    "            now += 2\n",
    "            ret['area'] = self.SBit16toNum(data[now : now + 2])\n",
    "            now += 2\n",
    "            ret['JBlevel'] = self.SBit16toNum(data[now : now + 2])\n",
    "            now += 2\n",
    "            ret['GZ'] = self.SBit16toNum(data[now : now + 2])\n",
    "            now += 2\n",
    "            ret['NOTauto'] = self.SBit16toNum(data[now : now + 2])\n",
    "            now += 2\n",
    "            ret['auto'] = self.SBit16toNum(data[now : now + 2])\n",
    "            now += 2\n",
    "            ret['shutdown'] = self.SBit16toNum(data[now : now + 2])\n",
    "            now += 2\n",
    "            ret['start'] = self.SBit16toNum(data[now : now + 2])\n",
    "            now += 2\n",
    "            # 启动控制\n",
    "            now += 2\n",
    "            # 延时\n",
    "            now += 2\n",
    "            ret['startRain'] = self.SBit16toNum(data[now : now + 2])\n",
    "            now += 2\n",
    "            ret['rain'] = self.SBit16toNum(data[now : now + 2])\n",
    "            # 预留\n",
    "\n",
    "        except Exception as e:\n",
    "            #print(e)\n",
    "            ret = self._ReportError_unkn\n",
    "        return ret\n",
    "\n",
    "    def formReport02(self):\n",
    "        ret = ''\n",
    "        try:\n",
    "            fes = self.dic['fes']\n",
    "            fs = self.dic['fs']\n",
    "            fq = self.dic['fq']\n",
    "            assert len(fes['values']) > 0\n",
    "            assert fes['number'] == len(fes['values'])\n",
    "            assert 'numJB' in fs\n",
    "            assert 'oc' in fs\n",
    "            assert 'co' in fs\n",
    "            assert 'fog' in fs\n",
    "            assert 'voc' in fs\n",
    "            assert 'area' in fq\n",
    "            ret += chr(0x70) + chr(0x00) + chr(0x01)\n",
    "            errlst = []\n",
    "            for each in fes['values']:\n",
    "                if each['error'] == True:\n",
    "                    errlst.append((DataFormer._dicMch2Num['fireEnder'], each))\n",
    "            for key, val in fs.items():\n",
    "                if type(val) == dict:\n",
    "                    if val['error'] == True:\n",
    "                        errlst.append((DataFormer._dicMch2Num[key], val))\n",
    "            ret += chr(len(errlst)) # 个数 1\n",
    "            ret += chr(0xff) + chr(0xff) # 预留 2\n",
    "            for each in errlst:\n",
    "                ret += self.Snum2ChrBit8(fq['area']) # 防护区 1\n",
    "                ret += self.Snum2ChrBit8(each[0]) # 设备类型 1\n",
    "                ret += self.Snum2ChrBit8(each[1]['id']) # 设备ID 1\n",
    "                ret += self.Snum2ChrBit8(1) # 故障码(无区分) 1\n",
    "                ret += chr(0xff) + chr(0xff) # 预留 2\n",
    "\n",
    "        except Exception as e:\n",
    "            print(e)\n",
    "            ret = self._report02fail\n",
    "        return ret\n",
    "\n",
    "    def parseReport02(self, data):\n",
    "        ret = {}\n",
    "        try:\n",
    "            if data[0] != chr(0x70): return self._ReportError_func\n",
    "            if data[1] != chr(0x00): return self._ReportError_read\n",
    "            now = 3\n",
    "            ret['length'] = ord(data[now])\n",
    "            now += 1\n",
    "            # 预留\n",
    "            now += 2\n",
    "            lst = []\n",
    "            for i in range(ret['length']):\n",
    "                dic = {}\n",
    "                dic['area'] = ord(data[now])\n",
    "                now += 1\n",
    "                dic['type'] = ord(data[now])\n",
    "                now += 1\n",
    "                dic['id'] = ord(data[now])\n",
    "                now += 1\n",
    "                dic['GZcode'] = ord(data[now])\n",
    "                now += 2\n",
    "                # 预留\n",
    "                now += 1\n",
    "                lst.append(dic)\n",
    "            ret['values'] = lst\n",
    "\n",
    "        except Exception as e:\n",
    "            print(e)\n",
    "            ret = self._ReportError_unkn\n",
    "        return ret\n",
    "\n",
    "    def formReport01(self):\n",
    "        ret = ''\n",
    "        try :\n",
    "            ret += chr(0x70) + chr(0x00) + chr(0x01)\n",
    "            ret += chr(4) # 个数\n",
    "            fes = self.dic['fes']\n",
    "            fs = self.dic['fs']\n",
    "            fq = self.dic['fq']\n",
    "            assert len(fes['values']) > 0\n",
    "            assert fes['number'] == len(fes['values'])\n",
    "            assert 'numJB' in fs\n",
    "            assert 'oc' in fs\n",
    "            assert 'co' in fs\n",
    "            assert 'fog' in fs\n",
    "            assert 'voc' in fs\n",
    "            assert 'FeelerNumber' in fs\n",
    "            GZcnt = 0\n",
    "            for each in fes['values']:\n",
    "                if each['error'] == True:\n",
    "                    GZcnt += 1\n",
    "            for val in fs.values():\n",
    "                if type(val) == dict:\n",
    "                    if val['error'] == True:\n",
    "                        GZcnt += 1\n",
    "            ret += self.Snum2ChrBit16(fq['area']) # 分区 2\n",
    "            ret += self.Snum2ChrBit16(fs['numJB']) # 警报个数 2\n",
    "            ret += self.Snum2ChrBit16(GZcnt) #  故障个数 2\n",
    "            ret += self.Snum2ChrBit16(fs['FeelerNumber']) # 探测器个数 2\n",
    "        \n",
    "        except Exception as e:\n",
    "            #print(e)\n",
    "            ret = self._report01fail\n",
    "        return ret\n",
    "\n",
    "    def parseReport01(self, data):\n",
    "        ret = {}\n",
    "        try :\n",
    "            if data[0] != chr(0x70): return self._ReportError_func\n",
    "            if data[1] != chr(0x00): return self._ReportError_read\n",
    "            now = 3\n",
    "            ret['length'] = ord(data[now])\n",
    "            now += 1\n",
    "            ret['area'] = self.SBit16toNum(data[now : now + 2])\n",
    "            now += 2\n",
    "            ret['JBnum'] = self.SBit16toNum(data[now : now + 2])\n",
    "            now += 2\n",
    "            ret['GZnum'] = self.SBit16toNum(data[now : now + 2])\n",
    "            now += 2\n",
    "            ret['FeelerNum'] = self.SBit16toNum(data[now : now + 2])\n",
    "        except Exception as e:\n",
    "            #print(e)\n",
    "            ret = self._ReportError_unkn\n",
    "        return ret"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 379,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['QN\\x00\\x16\\x01`\\x01p\\x00\\x01\\x04\\x00\\x01\\x00\\x00\\x00\\x05\\x00\\x04ÅE', 'QN\\x00.\\x01p\\x01p\\x00\\x01\\x05ÿÿ\\x01\\x05e\\x01ÿÿ\\x01\\x05f\\x01ÿÿ\\x01\\x05g\\x01ÿÿ\\x01\\x01É\\x01ÿÿ\\x01\\x04Ì\\x01ÿÿëE', 'QN\\x00(\\x01\\x80\\x01\\x80\\x00\\x01\\x0cÿÿ\\x00\\x01\\x00\\x00\\x00\\x05\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\x00ÿÿÿÿ\\x00\\x00\\x00\\x00ÿÿFE', 'QN\\x00&\\x01\\x90\\x01\\x90\\x00\\x01\\x0cÿÿ\\x00\\x01\\x00\\x00\\x00\\x01\\x00\\x00a¨\\x00dN \\x00\\nÿÿÿÿÿÿ0E', 'QN\\x00&\\x01\\xa0\\x01\\xa0\\x00\\x01\\x04\\x00\\x01\\x00e\\x00\\x00\\x00\\x01\\x00f\\x00\\x00\\x00\\x01\\x00g\\x00\\x00\\x00\\x01\\x00h\\x00\\x00®E']\n"
     ]
    }
   ],
   "source": [
    "a = DataFormer()\n",
    "a.setDic(DataFormer._testdata)\n",
    "t = a.formReport()\n",
    "print(t)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pybase import dataformer"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['QN\\x00\\x16\\x01`\\x01\\x00p\\x00\\x01\\x04\\x00\\x01\\x00\\x00\\x00\\x05\\x00\\x04ÞE', 'QN\\x00.\\x01p\\x01\\x00p\\x00\\x01\\x05ÿÿ\\x01\\x05e\\x01ÿÿ\\x01\\x05f\\x01ÿÿ\\x01\\x05g\\x01ÿÿ\\x01\\x01É\\x01ÿÿ\\x01\\x04Ì\\x01ÿÿ\\x17E', 'QN\\x00(\\x01\\x80\\x01\\x00\\x80\\x00\\x01\\x0cÿÿ\\x00\\x01\\x00\\x00\\x00\\x05\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\x00ÿÿÿÿ\\x00\\x00\\x00\\x00ÿÿbE', 'QN\\x00&\\x01\\x90\\x01\\x00\\x90\\x00\\x01\\x0cÿÿ\\x00\\x01\\x00\\x00\\x00\\x01\\x00\\x00a¨\\x00dN \\x00\\nÿÿÿÿÿÿÉE', 'QN\\x00&\\x01\\xa0\\x01\\x00\\xa0\\x00\\x01\\x04\\x00\\x01\\x00e\\x00\\x00\\x00\\x01\\x00f\\x00\\x00\\x00\\x01\\x00g\\x00\\x00\\x00\\x01\\x00h\\x00\\x00\\x07E']\n"
     ]
    }
   ],
   "source": [
    "a = dataformer.DataFormer()\n",
    "a.setDic(dataformer.DataFormer._testdata)\n",
    "t = a.formReport()\n",
    "print(t)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "222 222\n",
      "({'length': 4, 'area': 1, 'JBnum': 0, 'GZnum': 5, 'FeelerNum': 4}, 96)\n",
      "23 23\n",
      "({'length': 5, 'values': [{'area': 1, 'type': 5, 'id': 101, 'GZcode': 1}, {'area': 1, 'type': 5, 'id': 102, 'GZcode': 1}, {'area': 1, 'type': 5, 'id': 103, 'GZcode': 1}, {'area': 1, 'type': 1, 'id': 201, 'GZcode': 1}, {'area': 1, 'type': 4, 'id': 204, 'GZcode': 1}]}, 112)\n",
      "98 98\n",
      "({'length': 12, 'area': 1, 'JBlevel': 0, 'GZ': 5, 'NOTauto': 0, 'auto': 1, 'shutdown': 0, 'start': 0, 'startRain': 0, 'rain': 0}, 128)\n",
      "201 201\n",
      "({'length': 12, 'area': 1, 'Mtype': 'Light', 'Mid': 1, 'JBlevel': 0, 'oc': 25.0, 'co': 0.1, 'voc': 20.0, 'fog': 0.01}, 144)\n",
      "7 7\n",
      "([{'area': 1, 'id': 101, 'work': 0}, {'area': 1, 'id': 102, 'work': 0}, {'area': 1, 'id': 103, 'work': 0}, {'area': 1, 'id': 104, 'work': 0}], 160)\n"
     ]
    }
   ],
   "source": [
    "for i in range(5):\n",
    "    print(a.parseReport(t[i]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "q = a.formReplay(0xa0, 1, False, 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "160\n"
     ]
    }
   ],
   "source": [
    "print(a.parseReplay(q))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "('0x7f', '0xe0', '0xa0')"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "hex(127), hex(224), hex(160)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['22', '33', '44']"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "lst = ['11', '22', '33', '44']\n",
    "lst.pop(0)\n",
    "lst"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pybase import dataSR"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "ename": "",
     "evalue": "",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31mThe Kernel crashed while executing code in the the current cell or a previous cell. Please review the code in the cell(s) to identify a possible cause of the failure. Click <a href='https://aka.ms/vscodeJupyterKernelCrash'>here</a> for more info. View Jupyter <a href='command:jupyter.viewOutput'>log</a> for further details."
     ]
    }
   ],
   "source": [
    "a = dataSR.SR()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "a.receive()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "a.send('123456', ('8.130.23.101', 27013))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "a.inactive()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "None\n"
     ]
    }
   ],
   "source": [
    "print(a.getData())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "63 169\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'__DataFormer_report_crce_error___@_'"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from pybase import dataformer\n",
    "df = dataformer.DataFormer()\n",
    "test = 'QN\\x00\\x16\\x01`\\x01\\x00p\\x00\\x01\\x04\\x00\\x01\\x00\\x00\\x00\\x00\\x00\\x04?E'\n",
    "data = df.parseReport(test)\n",
    "data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{1, 2, 3}"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "set([1, 2, 3])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(2022, 5, 10, 18, 48, 27)"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import time\n",
    "time.localtime()[ : 6]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "ls = list([{'area': 5, 'id': 101, 'work': 1}, {'area': 5, 'id': 102, 'work': 1}, {'area': 5, 'id': 103, 'work': 1}, {'area': 5, 'id': 104, 'work': 1}])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import time"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "20220511142449"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "t = time.localtime()[ : 6]\n",
    "tm = t[0]\n",
    "for i in range(1, 6):\n",
    "    tm = (tm * 100) + t[i]\n",
    "tm"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tm > 0xffffffffffff"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [],
   "source": [
    "    def formTimeS(self):\n",
    "        t = time.localtime()[ : 6]\n",
    "        tm = t[0]\n",
    "        for i in range(1, 6):\n",
    "            tm = (tm * 100) + t[i]\n",
    "        ret = ''\n",
    "        for i in range(6):\n",
    "            ret = chr(tm & 0xff) + ret\n",
    "            tm >>= 8\n",
    "        return ret\n",
    "\n",
    "    def parseTimeS(self, data):\n",
    "        ret = 0\n",
    "        for each in data:\n",
    "            ret = (ret << 8) + ord(each)\n",
    "        return ret"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u0012côbD#\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "20220511142947"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    " a = formTimeS(1)\n",
    " print(a)\n",
    " parseTimeS(1, a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'asdf'"
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "'asdf123456E'[ : -7]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "int() argument must be a string, a bytes-like object or a number, not 'NoneType'",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-55-af2123a46eb2>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;32mNone\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m: int() argument must be a string, a bytes-like object or a number, not 'NoneType'"
     ]
    }
   ],
   "source": [
    "int(None)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [],
   "source": [
    "ss = '{\"1\": [{\"revID\": \"20220511150915106\", \"AREA\": 1, \"JBnum\": 0, \"GZnum\": 0, \"Fnum\": 4, \"sendTime\": \"20220511150916\"}], \"2\": [], \"3\": [{\"revID\": \"20220511150915107\", \"AREA\": 1, \"JBlevel\": 0, \"GZ\": 0, \"auto\": 1, \"notAuto\": 0, \"start\": 0, \"shutdown\": 0, \"rain\": 0, \"startRain\": 0, \"sendTime\": \"20220511150916\"}], \"4\": [{\"revID\": \"20220511150915108\", \"AREA\": 1, \"Mtype\": \"Light\", \"Mid\": 1, \"JBlevel\": 0, \"oc\": 25.0, \"co\": 0.1, \"voc\": 20.0, \"fog\": 0.01, \"sendTime\": \"20220511150916\"}], \"5\": [{\"revID\": \"20220511150915109\", \"AREA\": 1, \"id\": 101, \"status\": 0, \"sendTime\": \"20220511150916\"}, {\"revID\": \"20220511150915110\", \"AREA\": 1, \"id\": 102, \"status\": 0, \"sendTime\": \"20220511150916\"}, {\"revID\": \"20220511150915111\", \"AREA\": 1, \"id\": 103, \"status\": 0, \"sendTime\": \"20220511150916\"}, {\"revID\": \"20220511150915112\", \"AREA\": 1, \"id\": 104, \"status\": 0, \"sendTime\": \"20220511150916\"}]}'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [],
   "source": [
    "import json"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'1': [{'revID': '20220511150915106',\n",
       "   'AREA': 1,\n",
       "   'JBnum': 0,\n",
       "   'GZnum': 0,\n",
       "   'Fnum': 4,\n",
       "   'sendTime': '20220511150916'}],\n",
       " '2': [],\n",
       " '3': [{'revID': '20220511150915107',\n",
       "   'AREA': 1,\n",
       "   'JBlevel': 0,\n",
       "   'GZ': 0,\n",
       "   'auto': 1,\n",
       "   'notAuto': 0,\n",
       "   'start': 0,\n",
       "   'shutdown': 0,\n",
       "   'rain': 0,\n",
       "   'startRain': 0,\n",
       "   'sendTime': '20220511150916'}],\n",
       " '4': [{'revID': '20220511150915108',\n",
       "   'AREA': 1,\n",
       "   'Mtype': 'Light',\n",
       "   'Mid': 1,\n",
       "   'JBlevel': 0,\n",
       "   'oc': 25.0,\n",
       "   'co': 0.1,\n",
       "   'voc': 20.0,\n",
       "   'fog': 0.01,\n",
       "   'sendTime': '20220511150916'}],\n",
       " '5': [{'revID': '20220511150915109',\n",
       "   'AREA': 1,\n",
       "   'id': 101,\n",
       "   'status': 0,\n",
       "   'sendTime': '20220511150916'},\n",
       "  {'revID': '20220511150915110',\n",
       "   'AREA': 1,\n",
       "   'id': 102,\n",
       "   'status': 0,\n",
       "   'sendTime': '20220511150916'},\n",
       "  {'revID': '20220511150915111',\n",
       "   'AREA': 1,\n",
       "   'id': 103,\n",
       "   'status': 0,\n",
       "   'sendTime': '20220511150916'},\n",
       "  {'revID': '20220511150915112',\n",
       "   'AREA': 1,\n",
       "   'id': 104,\n",
       "   'status': 0,\n",
       "   'sendTime': '20220511150916'}]}"
      ]
     },
     "execution_count": 58,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "json.loads(ss)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [],
   "source": [
    "dic = {\n",
    "    'd' : {\n",
    "        'a' : {\n",
    "            'f' : 1,\n",
    "            22 : 3,\n",
    "        },\n",
    "        33 : 4,\n",
    "    },\n",
    "    33 :6,\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'{\"d\": {\"a\": {\"f\": 1, \"22\": 3}, \"33\": 4}, \"33\": 6}'"
      ]
     },
     "execution_count": 60,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "json.dumps(dic)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "interpreter": {
   "hash": "ad2bdc8ecc057115af97d19610ffacc2b4e99fae6737bb82f5d7fb13d2f2c186"
  },
  "kernelspec": {
   "display_name": "Python 3.8.8 ('base')",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
